package org.gbif.agi.action;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.gbif.agi.model.Taxon;
import org.gbif.agi.model.dto.TaxonDetail;
import org.gbif.agi.service.TaxonManager;

import com.opensymphony.xwork2.Action;

public class TaxonAction {
    private TaxonManager manager;
    private List<TaxonDetail> taxa = new LinkedList<TaxonDetail>();
    private Long taxonId;
    private Long datasourceId=7L;
    private Log log = LogFactory.getLog(this.getClass());

    public TaxonAction(TaxonManager manager) {
        this.manager = manager;
    }

    public String execute() {
        return Action.SUCCESS;
    }

    public String browse() {
    	List<Taxon> root = manager.getRootTaxa(datasourceId);
    	for (Taxon t : root) {
    		taxa.add(new TaxonDetail(t.getId(), t.getName(), t.getLeft(), t.getRight()));
    	}
        return Action.SUCCESS;
    }
    
    /**
     * @return An open tree
     */
    public String open() {
    	if (taxonId == null) {
    		return browse(); 
    	} else {
	    	Taxon t = manager.get(taxonId);
	    	TaxonDetail open = new TaxonDetail(t.getId(), t.getName(), t.getLeft(), t.getRight());
	    	log.info("Open taxon: " + open.getName());
	    	
	    	// open it and add the children
	    	log.info("Open taxon has " + t.getChildren().size() + " children.");
	    	for (Taxon child : t.getChildren()) {
	    		open.getChildren().add(new TaxonDetail(child.getId(), child.getName(), child.getLeft(), child.getRight()));
	    	}
	    	Collections.sort(open.getChildren());
	    	
	    	// iterate up to the root
	    	while (t.getParent() != null) {
	    		t = t.getParent();
	    		TaxonDetail parent = new TaxonDetail(t.getId(), t.getName(), t.getLeft(), t.getRight());
	    		parent.getChildren().add(open);
	    		open = parent;
	    	}
	    	
	    	List<Taxon> root = manager.getRootTaxa(datasourceId);
	    	for (Taxon rootItem : root) {
	    		if (rootItem.getId() == open.getId()) {
	    			taxa.add(open);
	    		} else {
	    			taxa.add(new TaxonDetail(rootItem.getId(), rootItem.getName(), rootItem.getLeft(), rootItem.getRight()));
	    		}
	    	}  	
	    	
	        return Action.SUCCESS;
    	}
    }
    
    

    public String buildNestedSet() {
    	manager.scheduleNestedSet(datasourceId);
    	return Action.SUCCESS;
    }

    public String tieTaxonomy() {
    	manager.scheduleTieGeneraToTaxonomy(datasourceId);
    	return Action.SUCCESS;
    }

	public TaxonManager getManager() {
		return manager;
	}

	public void setManager(TaxonManager manager) {
		this.manager = manager;
	}

	public List<TaxonDetail> getTaxa() {
		return taxa;
	}

	public void setTaxa(List<TaxonDetail> taxa) {
		this.taxa = taxa;
	}

	public Long getTaxonId() {
		return taxonId;
	}

	public void setTaxonId(Long taxonId) {
		this.taxonId = taxonId;
	}

	public Long getDatasourceId() {
		return datasourceId;
	}

	public void setDatasourceId(Long datasourceId) {
		this.datasourceId = datasourceId;
	}
}
